﻿using Engine;
using Game;
namespace Mekiasm.Common
{
    public class ItemElement : Element<Interface.IMekItemMachine>
    {
        public ComponentItemEnergyMachine Component;
        public ItemElement(int x, int y, int z) : base(x, y, z)
        {
            Component = Instance.Machine as ComponentItemEnergyMachine;
        }
        //从周围Inventory获取Value
        public void GetItem()
        {
            for (int i = 0; i < 6; i++)
            {
                Point3 cpoint = Point + CellFace.FaceToPoint3(i);
                int v = ILibrary.SubsystemTerrain.Terrain.GetCellValueFast(cpoint.X, cpoint.Y, cpoint.Z);
                //旁边有机器，推送本身物品给机器
                if (Component.Value.HasValue)
                {
                    SaveItemSystem.GetBlockData(v, out SaveItem toolSaveItem);
                    if (toolSaveItem != null && toolSaveItem.SlotsCount > 0)
                    {
                        bool flag = false;
                        for (int j = 0; j < toolSaveItem.SlotsCount; j++)
                        {
                            if (toolSaveItem.GetSlotCount(j) == 0 || (toolSaveItem.GetSlotCount(j) + 1 <= toolSaveItem.GetSlotCapacity(j, Component.Value.Value)))
                            {
                                toolSaveItem.AddSlotItems(j, Component.Value.Value, 1);
                                Component.Value = null;
                                Component.IsStartAnimate = false;
                                Component.MoveEndFlag = false;
                                flag = true;
                                break;
                            }
                        }
                        if (flag) break;
                    }
                }

                int thisF = i;
                int face = OppositeFace(thisF);
                Component.MachineFaceConfig.TryGetValue(thisF, out MachineFaceConfig configF);
                if (configF.MachineMode != MekBlock.MachineMode.IN) continue;
                if (Component.Value.HasValue) continue;
                //本身输入，邻居输出，由邻居推送给本身
                var element = Connections.Find(p => p.Point == cpoint);
                if (element != null)
                {
                    continue;//是管道，不操作
                }
                else
                {
                    ComponentBlockEntity blockEntity = ILibrary.SubsystemBlockEntities.GetBlockEntity(cpoint.X, cpoint.Y, cpoint.Z);
                    if (blockEntity != null)
                    {//从对方推送到本身
                        IInventory inventory = blockEntity.Entity.FindComponent<IInventory>();
                        if (inventory is ComponentEnergyMachine machine)
                        { //Mek设备
                            machine.MachineFaceConfig.TryGetValue(face, out MachineFaceConfig config);
                            bool flag = false;
                            if (config.DeviceType == MekBlock.DeviceType.Item && config.MachineMode == MekBlock.MachineMode.OUT && configF.MachineMode == MekBlock.MachineMode.IN)
                            {
                                for (int j = 0; j < machine.SlotsCount; j++)
                                {
                                    if (machine.GetSlotType(j).HasFlag(ComponentEnergyMachine.SlotType.OUT) && machine.GetSlotCount(j) > 0)
                                    {
                                        Component.Value = machine.GetSlotValue(j);
                                        Component.MoveEndFlag = true;
                                        machine.RemoveSlotItems(j, 1);
                                        flag = true;
                                        Sound.PlayOnce();
                                        break;
                                    }
                                }

                            }
                            if (flag) break;

                        }
                        else
                        { //其它设备
                            bool flag = false;
                            for (int j = 0; j < inventory.SlotsCount; j++)
                            {
                                if (inventory.GetSlotCount(j) > 0)
                                {
                                    Component.Value = inventory.GetSlotValue(j);
                                    Component.MoveEndFlag = true;
                                    inventory.RemoveSlotItems(j, 1);
                                    flag = true;
                                    Sound.PlayOnce();
                                    break;
                                }
                            }
                            if (flag) break;
                        }
                    }
                }
            }
        }
        //移动
        public void MoveItem(float SpeedControl = 0.01f)
        {
            if (Component.Value.HasValue && !Component.MoveEndFlag)
            {
                Component.NowPosition = Component.NowPosition + Component.Velocity * SpeedControl;
                switch (Component.MoveFromFace)
                {
                    case 0:
                        if (Component.NowPosition.Z >= Component.EndPosition.Z) Component.MoveEndFlag = true;
                        break;
                    case 1:
                        if (Component.NowPosition.X >= Component.EndPosition.X) Component.MoveEndFlag = true;
                        break;
                    case 2:
                        if (Component.NowPosition.Z <= Component.EndPosition.Z) Component.MoveEndFlag = true;
                        break;
                    case 3:
                        if (Component.NowPosition.X <= Component.EndPosition.X) Component.MoveEndFlag = true;

                        break;
                    case 4:
                        if (Component.NowPosition.Y >= Component.EndPosition.Y) Component.MoveEndFlag = true;

                        break;
                    case 5:
                        if (Component.NowPosition.Y <= Component.EndPosition.Y) Component.MoveEndFlag = true;

                        break;
                    default:

                        break;
                }
            }
        }
        //推出
        public void OutputItem()
        {
            if (Component.MoveEndFlag)
            {
                for (int i = 0; i < 6; i++)
                {
                    Point3 cpoint = Point + CellFace.FaceToPoint3(i);
                    int v = ILibrary.SubsystemTerrain.Terrain.GetCellValueFast(cpoint.X, cpoint.Y, cpoint.Z);
                    SaveItemSystem.GetBlockData(v, out Common.SaveItem toolSaveItem);
                    if (toolSaveItem != null && toolSaveItem.SlotsCount > 0)
                    {
                        bool flag = false;
                        for (int j = 0; j < toolSaveItem.SlotsCount; j++)
                        {
                            if ((toolSaveItem.GetSlotValue(j) == Component.Value.Value || toolSaveItem.GetSlotCount(j) == 0) && toolSaveItem.GetSlotCount(j) + 1 <= toolSaveItem.GetSlotCapacity(j, Component.Value.Value))
                            {
                                toolSaveItem.AddSlotItems(j, Component.Value.Value, 1);
                                Component.Value = null;
                                Component.IsStartAnimate = false;
                                Component.MoveEndFlag = false;
                                flag = true;
                                break;
                            }
                        }
                        if (flag) break;
                    }
                    int thisF = i;
                    int face = OppositeFace(thisF);
                    Component.MachineFaceConfig.TryGetValue(thisF, out MachineFaceConfig configF);
                    if (configF.MachineMode != MekBlock.MachineMode.OUT) continue;
                    var element = Connections.Find(p => p.Point == cpoint);
                    if (element != null)
                    {
                        //是管道
                        var neiborComponent = element.Instance as ComponentItemEnergyMachine;
                        neiborComponent.MachineFaceConfig.TryGetValue(face, out MachineFaceConfig config);
                        //本身出，对方入
                        if (config.MachineMode == MekBlock.MachineMode.IN)
                        {//从本身的Value推送到对方
                            if (!neiborComponent.Value.HasValue)
                            {
                                neiborComponent.Value = Component.Value;
                                neiborComponent.MoveEndFlag = false;
                                neiborComponent.StartPosition = Position;
                                neiborComponent.NowPosition = Position;
                                neiborComponent.EndPosition = element.Position;
                                neiborComponent.MoveFromFace = i;
                                neiborComponent.Velocity = element.Position - Position;
                                Component.Value = null;
                                Component.MoveEndFlag = false;
                            }
                        }
                    }
                    else
                    {
                        ComponentBlockEntity blockEntity = ILibrary.SubsystemBlockEntities.GetBlockEntity(cpoint.X, cpoint.Y, cpoint.Z);
                        if (blockEntity != null)
                        {//从本身推送到对方
                            IInventory inventory = blockEntity.Entity.FindComponent<IInventory>();
                            if (inventory != null)
                            {
                                if (Component.IsStartAnimate)
                                {

                                    if (inventory is ComponentEnergyMachine)
                                    { //Mek设备                                
                                        ComponentEnergyMachine machine = inventory as ComponentEnergyMachine;
                                        machine.MachineFaceConfig.TryGetValue(face, out MachineFaceConfig config);
                                        bool flag = false;
                                        if (config.DeviceType == MekBlock.DeviceType.Item && config.MachineMode == MekBlock.MachineMode.IN)
                                        {
                                            for (int j = 0; j < machine.SlotsCount; j++)
                                            {
                                                if (machine.GetSlotType(j) == ComponentEnergyMachine.SlotType.IN && (machine.GetSlotValue(j) == Component.Value.Value || machine.GetSlotCount(j) == 0) && machine.GetSlotCount(j) + 1 <= machine.GetSlotCapacity(j, Component.Value.Value))
                                                {
                                                    machine.AddSlotItems(j, Component.Value.Value, 1);
                                                    Component.Value = null;
                                                    Component.MoveEndFlag = false;
                                                    flag = true;
                                                    Component.IsStartAnimate = false;
                                                    break;
                                                }
                                            }

                                        }
                                        if (flag) break;

                                    }
                                    else
                                    { //其它设备
                                        bool flag = false;
                                        for (int j = 0; j < inventory.SlotsCount; j++)
                                        {
                                            if ((inventory.GetSlotValue(j) == Component.Value.Value || inventory.GetSlotCount(j) == 0) && inventory.GetSlotCount(j) + 1 <= inventory.GetSlotCapacity(j, Component.Value.Value))
                                            {
                                                inventory.AddSlotItems(j, Component.Value.Value, 1);
                                                Component.Value = null;
                                                Component.IsStartAnimate = false;
                                                Component.MoveEndFlag = false;
                                                flag = true;
                                                break;
                                            }
                                        }
                                        if (flag) break;
                                    }
                                }
                                else
                                {//构造推入动画
                                    Component.MoveEndFlag = false;
                                    Component.StartPosition = Position;
                                    Component.EndPosition = new Vector3(cpoint);
                                    Component.MoveFromFace = i;
                                    Component.Velocity = Component.EndPosition - Component.StartPosition;
                                    Component.IsStartAnimate = true;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
